=begin
Copyright (C) 2006  Kyle Brett <ksbrett@cc.gatech.edu>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
=end

module Sph
  module ObjectBrowser
    class InspectorView < Gtk::VBox
      # The object under inspection
      attr :subject
      
      # Create an InspectorView.  If you are handling the
      # inspector manually (as opposed to having a BrowserView
      # manage it) you can change the subject with setSubject.
      def initialize
        super
        @labels = Hash.new
        @subject = Hash.new
        __initInfoBox
        __initNotebook
      end
      
      private
      def __initInfoBox
        @topBox = Gtk::VBox.new
        @labels[:name] = Gtk::Label.new("<b>Object Name</b>")
        @labels[:name].use_markup = true
        @labels[:info] = Gtk::Label.new("Information")
        @labels[:info].wrap = true
        @topBox.pack_start(@labels[:name])
        @topBox.pack_start(@labels[:info])
        pack_start(@topBox, false)
      end
      
      def __initNotebook
        @methodsPane = Gtk::VBox.new
        @varsPane = Gtk::VBox.new
        @notebook = Gtk::Notebook.new
        @notebook.append_page(@varsPane, Gtk::Label.new("Variables"))
        @notebook.append_page(@methodsPane, Gtk::Label.new("Methods"))
        @notebook.signal_connect("switch_page") do |x, xx, pageNum|
          pageNum == 1 ? exposeMethodsPane : exposeVarsPane
        end
        expander = Gtk::Expander.new("More")
        expander.add(@notebook)
        expander.signal_connect("activate") do |expander|
          parent = expander.parent
          expanded = parent.query_child_packing(expander)[0]
          packing = expanded ? false : true
          parent.remove(expander)
          expander.label = "More" if expanded
          expander.label = "Less" if not expanded
          parent.pack_end(expander, packing)
        end
        pack_end(expander, false)
        __initNotebookPanes
      end
      
      def __initNotebookPanes
        __initVarsPane
        __initMethodsPane
      end
      
      def __initVarsPane
        @varsTree = Gtk::TreeView.new(Gtk::ListStore.new(String, String))
        ren = Gtk::CellRendererText.new
        col = Gtk::TreeViewColumn.new("Identifier", ren, :text => 0)
        ren = Gtk::CellRendererText.new
        col2 = Gtk::TreeViewColumn.new("Value", ren, :text => 1)
        [col, col2].each do |col|
          col.resizable = true
          @varsTree.append_column(col)
        end
        @varsPane.add(Sph::scroller(@varsTree))
      end
      
      def __initMethodsPane
        @methodsTree = Gtk::TreeView.new(Gtk::ListStore.new(String, String))
        ren = Gtk::CellRendererText.new
        col = Gtk::TreeViewColumn.new("Method", ren, :text => 0)
        ren = Gtk::CellRendererText.new
        col2 = Gtk::TreeViewColumn.new("Info", ren, :text => 1)
        [col, col2].each do |col|
          col.resizable = true
          @methodsTree.append_column(col)
        end
        @methodsPane.add(Sph::scroller(@methodsTree))
      end
      
      def exposeVarsPane
        ls = @varsTree.model
        ls.clear
        @subject[:object].instance_variables.each do |ivar|
          iter = ls.append
          iter[0] = ivar
          iter[1] = @subject[:object].instance_variable_get(ivar).inspect
        end
      end
      
      def exposeMethodsPane
        ls = @methodsTree.model
        ls.clear
        @subject[:object].public_methods(false).each do |meth|
          iter = ls.append
          iter[0] = meth
          iter[1] = "params?"
        end
      end
      
      def refresh
        @labels[:name].markup = "<b>#{@subject[:name]}</b>"
        @labels[:info].text = @subject[:object].inspect
        @notebook.page == 1 ? exposeMethodsPane : exposeVarsPane
      end
      
      public
      # Change the subject under inspection.  <tt>object</tt>
      # is the object to inspect, <tt>name</tt> is an identifier,
      # really of your choosing, though BrowserView will try to
      # use a real identifier from the program context.
      def setSubject(object, name)
        @subject[:object] = object
        @subject[:name] = name
        refresh
      end
    end #class InspectorView
  end #module ObjectBrowser
end #module Sp